package com.bardpub.controls 
{
	import com.greensock.easing.Back;
	import com.greensock.plugins.AutoAlphaPlugin;
	import com.greensock.plugins.TweenPlugin;
	import com.greensock.TweenLite;
	import flash.accessibility.AccessibilityProperties;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.display.Sprite;
	import flash.display.Stage;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.filters.DropShadowFilter;
	import flash.geom.Point;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;
	/**
	 * ...
	 * @author bardpub
	 */
	public class BToolTip extends BComponent
	{
		private var __dir:int = 0;					//方向 等待fix
		private var __widthLimit:Number = 100;		//最大宽度
			
		private var _arrow:BToolTipArrow;			//箭头
		private var _bg:Sprite;						//背景
		private var _txt:TextField;					//文本
		private var _multiline:Boolean = false;		//是否多行
		private var _tip:String = "";				//显示文本
		private var _canvas:BitmapData;				//画布，用来把文本绘制为位图
		private var _bmp:Bitmap;					
		private var _txtColor:String = "#000000";	//文本颜色
		private var _txtSize:int = 12;				//文字大小
		
		
		private static var _instance:BToolTip;
		private var _stage:Stage;
		
		
		/**
		 * 创建 com.bardpub.controls.BToolTip 类的新实例
		 * 禁止直接实例化
		 * @param	parent	父元素
		 * @param	x		组件相对于父元素的x坐标
		 * @param	y		组件相对于父元素的y坐标
		 */
		public function BToolTip(parent:DisplayObjectContainer = null, x:Number = 0, y:Number = 0)  
		{
			super(parent, x, y);
			this.alpha = 0;
			this.visible = false;
			this.filters = [new DropShadowFilter(2, 45, 0, .5)];
			mouseChildren = mouseEnabled = false;
		}
		
		/**
		 * 注册 BToolTip
		 * @param	display
		 * @return
		 */
		public function init(display:DisplayObject):Boolean
		{
			if (display is Stage)
			{
				_stage = display as Stage;
			}
			
			while (display.parent != null)
			{
				display = display.parent;
				if (display is Stage)
				{
					_stage = display as Stage;
					break;
				}
			}
			if (_stage == null)
			{
				throw new Error("注册失败,请传递一个任意已存在显示列表中的对象来进行注册");
				return false;
			}
			
			return true;
		}

		/**
		 * 初始化 BToolTip
		 * @param	display
		 * @return  
		 */
		public static function init(display:DisplayObject):Boolean
		{
			return getInstance().init(display);
		}
		
		/**
		 * 注册显示对象
		 * @param	area		要注册的显示对象
		 * @param	msg			要显示的消息
		 * @param	offset		ToopTip显示时基于显示对象的距离
		 */
		public static function register(area:DisplayObject, msg:String,  offset:Point = null):void 
		{
			if (offset == null) 
				offset = new Point(0, 0);
			getInstance().register(area, msg, offset);
		}
		
		public static function unregister(area:DisplayObject):void 
		{
			getInstance().unregister(area);
		}
		
		
		public static function active(area:DisplayObject, show:Boolean = true):void 
		{
			getInstance().active(area, show);
		}
		
	
		public static function hide():void 
		{
			getInstance().hidden();
		}
		
		/**
		 * 注册显示对象
		 * @param	area		要注册的显示对象
		 * @param	msg			要显示的消息
		 * @param	offset		ToopTip显示时基于显示对象的距离
		 */
		public function register(area:DisplayObject, msg:String, offset:Point):void 
		{
			var prop:AccessibilityProperties = new AccessibilityProperties();
			prop.description = msg;
			prop.name = offset.x + "|" + offset.y;
			area.accessibilityProperties = prop;
			
			area.addEventListener(Event.REMOVED_FROM_STAGE, onRemoveFromStage);
			area.addEventListener(MouseEvent.ROLL_OVER, rollOverHandler);
			area.addEventListener(MouseEvent.ROLL_OUT, rollOutHandler);
			
		}
		
		public function unregister(area:DisplayObject):void 
		{
			area.removeEventListener(Event.REMOVED_FROM_STAGE, onRemoveFromStage);
			area.removeEventListener(MouseEvent.ROLL_OVER, rollOverHandler);
			area.removeEventListener(MouseEvent.ROLL_OUT, rollOutHandler);
		}
		
		public  function active(area:DisplayObject, show:Boolean = true):void 
		{
			if (show)
			{
				area.addEventListener(MouseEvent.ROLL_OVER, rollOverHandler);
				area.addEventListener(MouseEvent.ROLL_OUT, rollOutHandler);
			}
			else 
			{
				area.removeEventListener(MouseEvent.ROLL_OVER, rollOverHandler);
				area.removeEventListener(MouseEvent.ROLL_OUT, rollOutHandler);
			}
		}
		
		private function rollOverHandler(e:MouseEvent):void 
		{
			var target:DisplayObject = e.target as DisplayObject;
			
			var tmp:Array = target.accessibilityProperties.name.split("|");
			var offset:Point = new Point(tmp[0], tmp[1]);
			
			var p:Point = target.localToGlobal(new Point(offset.x, offset.y));
			
			tip = target.accessibilityProperties.description;
			show(p.x, p.y);
			
		}
		
		private function rollOutHandler(e:MouseEvent):void 
		{
			hidden();
		}
		
		private function onRemoveFromStage(e:Event):void 
		{
			var display:DisplayObject = DisplayObject(e.target);
			
			unregister(display);
			
		}
		
		
		
		
		
		
		/**
		 * 获取实例
		 * @return BToolTip的实例
		 */
		private static function getInstance():BToolTip 
		{
			if (_instance == null)
			{
				_instance = new BToolTip(null, 0, 0);
			}
			return _instance;
		}
		
		/**
		 * 显示到指定坐标
		 * @param	x		
		 * @param	y
		 */
		public function show(x:Number, y:Number):void 
		{
			
			if (this.parent == null)
			{
				_stage.addChild(this);
			}
			this.alpha = 0;
			move(x + 20, y );
			TweenPlugin.activate([AutoAlphaPlugin]);
			TweenLite.to(this, .7, { autoAlpha:1, x:x,  ease:Back.easeOut } );
		}
		
		/**
		 * 隐藏
		 */
		public function hidden():void 
		{
			if (this.parent == null)
				return;
			TweenLite.to(this, .5, { autoAlpha:0, x:x+20,  ease:Back.easeOut , onComplete:onHiddenComplete} );
		}
		
		private function onHiddenComplete():void 
		{
			if (contains(this))
			{
				_stage.removeChild(this);
			}
		}
		
		
		/**
		 * 添加子对象
		 */
		override protected function addChildren():void 
		{
			var ref:Class = getClassByName("com.bardpub.controls.BToolTipArrow");
			_arrow = new ref() as BToolTipArrow;
			addChild(_arrow);
			
			ref = getClassByName("com.bardpub.controls.BToolTipArrowBg");
			_bg = new ref() as Sprite;
			addChild(_bg);
			_bg.width = widthLimit;
			_bg.x = _arrow.width;
			
			_txt = new TextField();
			_txt.defaultTextFormat = new TextFormat("arial", 12);
			_txt.width = __widthLimit - 10;
			_txt.autoSize = TextFieldAutoSize.LEFT;
			_txt.multiline = _multiline;
		}
		
		/**
		 * 绘制组件
		 */
		override public function draw():void 
		{
			super.draw();
			var color:uint = uint("0x" + _txtColor.substring(1));
			_txt.defaultTextFormat = new TextFormat(null, _txtSize, color); 
			_txt.width = __widthLimit-10;
			_txt.multiline = _multiline;
			_txt.wordWrap = _multiline;
			_txt.text = _tip;
			
			if (_tip == "") tip = " ";
			
			createCanvas();
			_bg.width = _bmp.width + 10;
			_bg.height = _bmp.height + 17;
			_canvas.draw(_txt);
			
		}
		
		/**
		 * 创建画布
		 */
		private function createCanvas():void 
		{
			if (_canvas != null)
			{
				_canvas.dispose();
				removeChild(_bmp);
				_bmp = null;
				
			}
			
			var bWidth:Number = _txt.textWidth - 10 > __widthLimit ? __widthLimit - 10 : _txt.textWidth + 1;
			
			_canvas = new BitmapData(bWidth || 10,
			                         _txt.textHeight || 10 , 
									 true, 
									 0);
			_bmp = new Bitmap(_canvas);
			addChild(_bmp);
			_bmp.x = 12;
			_bmp.y = -_bmp.height / 2-2;
			
		}
		
		/**
		 * 获取/设置宽度限制
		 */
		public function get widthLimit():Number { return __widthLimit; }
		public function set widthLimit(value:Number):void 
		{
			__widthLimit = value;
			invalidate();
		}
		
		/**
		 * 获取/设置文字是否多行
		 */
		public function get multiline():Boolean { return _multiline; }
		public function set multiline(value:Boolean):void 
		{
			_multiline = value;
			invalidate();
		}
		
		/**
		 * 获取/设置 提示文本
		 */
		public function get tip():String { return _tip; }
		public function set tip(value:String):void 
		{
			_tip = value;
			invalidate();
		}
		
		/**
		 * 获取/设置文字颜色(html表示法)
		 */
		public function get txtColor():String { return _txtColor; }
		public function set txtColor(value:String):void 
		{
			_txtColor = value;
			invalidate();
		}
		
		/**
		 * 获取/设置 文字大小
		 */
		public function get txtSize():int { return _txtSize; }
		public function set txtSize(value:int):void 
		{
			_txtSize = value;
			invalidate();
		}
		
		
	}

}